﻿using System;
using System.Web;
using BusinessBingo.Web.Infrastructure.InfoStores.Interfaces;
using BusinessBingo.Web.Infrastructure.InfoStores.Keys;

namespace BusinessBingo.Web.Infrastructure.InfoStores.HttpAbstractions
{
    /// <summary>
    /// ICacheRepository Implementation based on Http.Cache
    /// </summary>
    public class HttpCacheRepository : ICacheRepository
    {
        /// <summary>
        /// Adds an element to the cache
        /// </summary>
        /// <typeparam name="T">Type of the element</typeparam>
        /// <param name="key">CacheKey for Store</param>
        /// <param name="data">Data to store</param>
        public void AddElement<T>(CacheKeys key, T data)
        {
            HttpContext.Current.Cache[key.ToString()] = data;
        }

        /// <summary>
        /// Get a specific element of the cache based on the type and key
        /// </summary>
        /// <typeparam name="T">Type of the element</typeparam>
        /// <param name="key">Specific SessionKey</param>
        /// <returns>The element from the session</returns>
        public T GetElement<T>(CacheKeys key)
        {
            return (T)HttpContext.Current.Cache[key.ToString()];
        }

        /// <summary>
        /// Checks if a element is in the cache based on the key and type
        /// </summary>
        /// <typeparam name="T">Type of the element</typeparam>
        /// <param name="key">CacheKey for lookup</param>
        /// <returns>
        /// true if element is found and has the correct type, false if the key doesn´t exists or it has the wrong type
        /// </returns>
        public bool HasElement<T>(CacheKeys key)
        {
            return HttpContext.Current.Cache[key.ToString()] is T;
        }

        /// <summary>
        /// Deletes a element in the cache based on the key
        /// </summary>
        /// <param name="key">CacheKey for lookup</param>
        public void DeleteElement(CacheKeys key)
        {
            HttpContext.Current.Cache.Remove(key.ToString());
        }

        /// <summary>
        /// Updates and element
        /// </summary>
        /// <typeparam name="T">Type of the element</typeparam>
        /// <param name="key">CacheKey for lookup</param>
        /// <param name="data">New data for storing</param>
        /// <exception cref="InvalidOperationException">Exception is thrown if element doesn´t exists</exception>
        public void UpdateElement<T>(CacheKeys key, T data)
        {
            if (this.HasElement<T>(key) == true) HttpContext.Current.Cache[key.ToString()] = data;
            else throw new InvalidOperationException("Key does not exist");
        }
    }
}